<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body style="height: 2000px">
    <style></style>
    <script>
      document.onscroll = throttle(function () {
        console.log("callback");
      }, 2000);

      // 节流是在某个时间范围内只能执行一次，
      // 定义一个嵌套函数，入参是回调函数和时间范围
      // 通过上次执行时间变量，比对当前的时间是否超过上次执行时间+时间范围，是的话就执行回调并且把现在的时间记录为上一次

      function throttle1(callback, timeout) {
        let pre = 0;
        return function () {
          // 计算时间差（当前时间-上次执行的时间），小于时间范围，不执行
          const now = Date.now()
          if (now-pre <= timeout) {
            return;
          }
          pre =now
          callback.call();
        };
      }

      /*
      您提供的 throttle 函数实现了一个基本的节流功能，但是在某些情况下可能无法按预期工作。问题在于，当多次快速调用节流函数时，它没有正确地推迟回调函数 callback 的执行到 timeout 时间之后。如果在短时间内多次触发节流函数，callback 可能会被多次执行，而不是只执行一次。

为了解决这个问题，我们需要使用一个标志来确保 callback 只在 timeout 时间后执行一次。以下是修正后的节流函数实现：
      */

      function throttle(callback, timeout) {
        let inProgress = false;
        let pre = 0;
        return function () {
          // 计算时间差（当前时间-上次执行的时间），小于时间范围，不执行
          const now = Date.now()
          if (inProgress || now-pre <= timeout) {
            return;
          }
          pre =now

          inProgress = true;
          callback.call();
          inProgress = false; // 回调函数执行完毕，重置标记
          //   setTimeout(() => {

          //   }, 0);
        };
      }

      function testThrottle() {
        let callCount = 0;
        const callback = function () {
          callCount++;
          console.log(
            "Callback executed:",
            callCount,
            "at",
            new Date().toISOString()
          );
        };

        const throttledCallback = throttle(callback, 1000); // 设置节流时间为250毫秒

        const testInterval = setInterval(() => {
          throttledCallback(); // 模拟连续触发事件
        }, 2); // 每50毫秒触发一次

        // 运行测试2秒钟
        setTimeout(() => {
          clearInterval(testInterval);
          console.log("Test finished. Total calls:", callCount);
        }, 2000);
      }

      testThrottle();
    </script>
  </body>
</html>
